Dynamic Memory
IDL provides access to the dynamic memory allocation routines it uses internally. Use these routines rather than system-provided routines such as malloc()/free() when possible.
Note: The memory pointers returned by the IDL memory allocation routines discussed in this section do not necessarily correspond directly to malloc()/free() calls, or to any other system memory allocation package. You must be careful not to mix memory allocation packages. Memory allocated via a given API can only be freed by the corresponding free call provided by that API. For example, memory allocated by an IDL memory allocation routine can only be freed by the IDL IDL_MemFree() function. Memory allocated by malloc() can only be freed by free(). Failure to follow this rule can lead to memory corruption, including possible crashing of the IDL program.
Please note that code called via CALL_EXTERNAL, or as a system routine (LINKIMAGE, Dynamically Loadable Modules) should not use the IDL dynamic memory routines. Instead, use IDL_GetScratch() (see “Getting Dynamic Memory") which prevents memory from being lost under error conditions.
Note: Our experience shows that in situations where IDL_GetScratch() is appropriate, use of any other memory allocation mechanism should raise a warning flag to the programmer that something is wrong in their code. Rarely if ever is a direct call to malloc()/free() reasonable in such a situation; even if it appears to work correctly, you will have to work harder to provide the error handling functionality that IDL_GetScratch() provides automatically, or your code will leak memory in such situations.
IDL_MemAlloc()
IDL_MemAlloc() is used to allocate dynamic memory.
void *IDL_MemAlloc(IDL_MEMINT n, char *err_str, int action)
where:
n
The number of bytes to allocate.
err_str
NULL, or a null terminated text string describing the memory being allocated.
action
An action parameter to be passed to IDL_Message() if IDL_MemAlloc() is unable to allocate the desired memory and err_str is non-NULL.
IDL_MemAlloc() attempts to allocate the desired amount of memory. If the requested amount is allocated, a pointer to the memory is returned. The memory is aligned strictly enough to be suitable for any object.
If the attempt to allocate memory fails and err_str is non-NULL, IDL_Message() is called as:
IDL_Message(IDL_M_CNTGETMEM, action, err_str)
If IDL_Message() returns, or if err_str is NULL and IDL_Message() is not called, IDL_MemAlloc() returns a NULL pointer indicating its failure.
IDL_MemFree()
Memory allocated via IDL_MemAlloc() should only be returned via IDL_MemFree():
void IDL_MemFree(REGISTER void *m, char *err_str, int action)
m
A pointer to memory previously allocated via IDL_MemAlloc().
err_str
NULL, or a null terminated text string describing the memory being freed.
action
An action parameter to be passed to IDL_Message() if unable to free memory and err_str is non-NULL.
IDL_MemFree() attempts to free the specified memory. If the attempt to free memory fails and err_str is non-NULL, IDL_Message() is called as:
IDL_Message(IDL_M_CNTFREMEM, action, err_str)
The following actions have undefined consequences, and should not be done:
- Returning memory allocated from a source other than IDL_MemAlloc().
- Freeing the same allocation more than once.
- Dereferencing memory once it has been freed.
IDL_MemAllocPerm()
Another memory allocation routine, IDL_MemAllocPerm(), exists to allocate dynamic memory that will not be returned for reuse. IDL_MemAllocPerm() allocates memory in moderately large units and carves out pieces of these blocks to satisfy its requests. Use of this routine can help minimize the effects of memory fragmentation.
void *IDL_MemAllocPerm(IDL_MEMINT n, char *err_str, int action)
IDL_MemAllocPerm() takes the same arguments as IDL_MemAlloc(), differing only in that the memory allocated will not be freed until the process exits. Do not attempt to free memory allocated by IDL_MemAllocPerm(). The results of such an action are undefined.